Skip to content

Conversation

@tjshiu
Copy link
Contributor

@tjshiu tjshiu commented Nov 17, 2025

This commit introduces two new inputs to the CDK overlay, providing more granular control over how popovers are inserted into the DOM:

  • cdkCustomPopoverInsertionElement: Allows specifying a custom element to be used as the host for
    the popover. The popover will be inserted after this element in the DOM.

This is necessary for cases where we need to move the popover element needs to be in an element that is not the origin:
E.g.: Here the ngMenu needs to have the popover as a child, but we still want the great positioning and styles by having the origin on the fileItem menu item.

<div ngMenuBar>
  <div ngMenuItem #fileItem value="File" [submenu]="fileMenu">File</div>
    <div ngMenu #fileMenuElement #fileMenu="ngMenu">
        <ng-template 
            [cdkConnectedOverlay]="{origin: fileItem, usePopover: 'inline'}"
            [cdkCustomPopoverInsertionElement]="fileMenuElement"
            cdkAttachPopoverAsChild
            [cdkConnectedOverlayOpen]="fileMenu.visible()">
              <div ngMenuItem value="New">New</div>
              <div ngMenuItem value="Open">Open</div>
              <div ngMenuItem value="Exit">Exit</div>
        </ng-template>
    </div>

  <div ngMenuItem #editItem value="Edit" [submenu]="editMenu">Edit</div>
    <div ngMenu #editMenuElement #editMenu="ngMenu">
        <ng-template
          [cdkConnectedOverlay]="{origin: editItem, usePopover: 'inline'}"
          [cdkCustomPopoverInsertionElement]="editMenuElement"
          cdkAttachPopoverAsChild
          [cdkConnectedOverlayOpen]="editMenu.visible()">
            <div ngMenuItem value="Cut">Cut</div>
            <div ngMenuItem value="Copy">Copy</div>
            <div ngMenuItem value="Paste">Paste</div>
        </ng-template>
    </div>
</div>
  • cdkAttachPopoverAsChild: A boolean that, when true, attaches the popover as a child of the popove
    host, rather than as a sibling.

This allows us to avoid adding a child element on ngMenu
BEFORE:

<button #trigger ngMenuTrigger [menu]="optionMenu">...</button>

<div ngMenu #optionMenu="ngMenu">
  <div #origin>
    <ng-template
      [cdkConnectedOverlay]="{origin, usePopover: 'inline'}"
      [cdkConnectedOverlayOpen]="optionMenu.visible()">
      <ng-template ngMenuContent>
        <div ngMenuItem value="1">...</div>
        <div ngMenuItem value="2">...</div>
        <div ngMenuItem value="3">...</div>
      </ng-template>
    </ng-template>
  </div>
</div>

AFTER:

<button #trigger ngMenuTrigger [menu]="optionMenu">...</button>

<div ngMenu #origin #optionMenu="ngMenu">
    <ng-template
      [cdkConnectedOverlay]="{origin, usePopover: 'inline'}"
      [cdkConnectedOverlayOpen]="optionMenu.visible()"
      cdkAttachPopoverAsChild>
        <div ngMenuItem value="Option 1">Option 1</div>
        <div ngMenuItem value="Option 2">Option 2</div>
        <div ngMenuItem value="Option 3">Option 3</div>
    </ng-template>
</div>

@tjshiu tjshiu requested a review from a team as a code owner November 17, 2025 11:54
@tjshiu tjshiu requested review from crisbeto and ok7sai and removed request for a team November 17, 2025 11:54
@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: cdk/overlay labels Nov 17, 2025
@tjshiu
Copy link
Contributor Author

tjshiu commented Nov 17, 2025

AFTER:

<div ngMenuBar>
  <div ngMenuItem #fileItem value="File" [submenu]="fileMenu">File</div>
    <div ngMenu #fileMenuElement #fileMenu="ngMenu">
        <ng-template 
            [cdkConnectedOverlay]="{origin: fileItem, usePopover: {parent: fileMenuElement}}"
            [cdkConnectedOverlayOpen]="fileMenu.visible()">
              <div ngMenuItem value="New">New</div>
              <div ngMenuItem value="Open">Open</div>
              <div ngMenuItem value="Exit">Exit</div>
        </ng-template>
    </div>

  <div ngMenuItem #editItem value="Edit" [submenu]="editMenu">Edit</div>
    <div ngMenu #editMenuElement #editMenu="ngMenu">
        <ng-template
          [cdkConnectedOverlay]="{origin: editItem, usePopover:  {parent: editMenuElement}}"
          [cdkConnectedOverlayOpen]="editMenu.visible()">
            <div ngMenuItem value="Cut">Cut</div>
            <div ngMenuItem value="Copy">Copy</div>
            <div ngMenuItem value="Paste">Paste</div>
        </ng-template>
    </div>
</div>
<button
  #menuTrigger
  ngMenuTrigger
  [menu]="optionMenu"
  aria-label="Open Menu">
  <span aria-hidden="true" class="material-symbols-outlined">more_vert</span>
</button>

<div ngMenu #menu #optionMenu="ngMenu">
    <ng-template
      [cdkConnectedOverlay]="{origin: menu, usePopover: {parent: menu}}"
      [cdkConnectedOverlayOpen]="optionMenu.visible()">
        <div ngMenuItem value="Option 1">Option 1</div>
        <div ngMenuItem value="Option 2">Option 2</div>
        <div ngMenuItem value="Option 3">Option 3</div>
    </ng-template>
</div>

@tjshiu tjshiu added the target: rc This PR is targeted for the next release-candidate label Nov 17, 2025
@tjshiu tjshiu removed the detected: feature PR contains a feature commit label Nov 17, 2025
@tjshiu tjshiu changed the title feat(cdk/overlay): enhance popover insertion control with new inputs refactor(cdk/overlay): enhance popover insertion control with new inputs Nov 17, 2025
This commit introduces two new inputs to the CDK overlay, providing more granular control over how popovers are inserted into the DOM:

- : Allows specifying a custom element to be used as the host for the popover. The popover will be inserted after this element in the DOM.

- : A boolean that, when true, attaches the popover as a child of the popover host, rather than as a sibling.
This commit refactors the popover insertion logic in the CDK overlay by removing  and  in favor of a more flexible  API. This change simplifies the API and provides more granular control over where popovers are inserted into the DOM.
disposeOnNavigation?: boolean;
usePopover?: FlexibleOverlayPopoverLocation | null;
customPopoverHostElement?: CdkOverlayOrigin | FlexibleConnectedPositionStrategyOrigin | null;
attachPopoverAsChild?: boolean;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can drop these two?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thanks!

@tjshiu tjshiu added the action: merge The PR is ready for merge by the caretaker label Nov 17, 2025
@tjshiu tjshiu removed the request for review from ok7sai November 17, 2025 21:18
@tjshiu tjshiu merged commit a3b985f into angular:main Nov 17, 2025
22 of 25 checks passed
@tjshiu
Copy link
Contributor Author

tjshiu commented Nov 17, 2025

This PR was merged into the repository. The changes were merged into the following branches:

tjshiu added a commit that referenced this pull request Nov 17, 2025
…uts (#32362)

* refactor(cdk/overlay): enhance popover insertion control with new inputs

This commit introduces two new inputs to the CDK overlay, providing more granular control over how popovers are inserted into the DOM:

- : Allows specifying a custom element to be used as the host for the popover. The popover will be inserted after this element in the DOM.

- : A boolean that, when true, attaches the popover as a child of the popover host, rather than as a sibling.

* refactor(cdk/overlay): simplify popover insertion logic

This commit refactors the popover insertion logic in the CDK overlay by removing  and  in favor of a more flexible  API. This change simplifies the API and provides more granular control over where popovers are inserted into the DOM.

* refactor(cdk/overlay): add overlay changes

* refactor(cdk/overlay): streamline popover insertion point logic

* fix(cdk/overlay): update the insertionpoint type

(cherry picked from commit a3b985f)
@tjshiu tjshiu deleted the overlay-copy branch November 17, 2025 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: cdk/overlay target: rc This PR is targeted for the next release-candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants